
# below is the template for creating the edit dialog
# it assumes a number of css and javascript files have been included.
TEMPLATE = """
{{env whiff.content_type: "text/html"
/}}

{{require %(jsonvar)s}}
  %(jsonData)s
{{/require}}

<script>
// modal edit dialog generated from template
//     displayUrl = %(displayUrl)s
//     editUrl = %(editUrl)s
//     editActionUrl = %(editActionUrl)s
// relativeUrl = %(relativeUrl)s

var %(jsonvar)s = {{include "whiff_middleware/asJson"}} {{use %(jsonvar)s/}} {{/include}};

function %(updateFnName)s (jsonString, action) {
	 %(jsonvar)s = jsonString;
	 {{include "whiff_middleware/CallPageFunction"}}
	 	 {{using page}}
		 	 {{include "whiff_middleware/setInnerHtml"}}
			 	 {{using elementName}} %(widgetContainer)s {{/using}}
				 {{using page}}
				 	 {{include "%(displayUrl)s"/}}
				 {{/using}}
			 {{/include}}
		 {{/using}}
	 	 {{using cgi_pairs}} [["jsonData", %(jsonvar)s]] {{/using}}
		 {{using doCall}} true {{/using}}
	 {{/include}};
         if (action) {
                 %(editFunctionName)s (action);
         }
}

function %(editFunctionName)s (action) {
	 {{include "whiff_middleware/CallPageFunction"}}
	 	 {{using page}}
		 	 {{include "whiff_middleware/setInnerHtml"}}
			 	 {{using elementName}} %(promptDiv)s {{/using}}
				 {{using page}}
				 	 {{include "%(editUrl)s"/}}
				 {{/using}}
			 {{/include}}
		 {{/using}}
	 	 {{using cgi_pairs}} 
		 	 [
			 ["jsonData", %(jsonvar)s],
			 ["action", action]
			 ] 
	         {{/using}}
		 {{using doCall}} true {{/using}}
	 {{/include}};
	 %(showPromptFnName)s ();
}

function %(changeFunctionName)s () {
	 %(closeFunctionName)s ();
         var pairs = %(editPairsAction)s;
         pairs.push( ["jsonData", %(jsonvar)s] );
         pairs.push( ["updateFnName", "%(updateFnName)s"] );
	 {{include "whiff_middleware/CallPageFunction"}}
	 	 {{using page}}
       		 	   {{include "%(editActionUrl)s"/}}
		 {{/using}}
	 	 {{using cgi_pairs}} 
                         pairs
	         {{/using}}
		 {{using doCall}} true {{/using}}
	 {{/include}};
	 %(updateFnName)s ( %(jsonvar)s );
}

</script>

<div id="%(widgetContainer)s">

{{include "%(displayUrl)s"}}
	  {{set-cgi jsonData}} {{use %(jsonvar)s/}} {{/set-cgi}}
{{/include}}

</div>

<div id="%(promptDialog)s">
     <div id="%(promptDiv)s">%(displayUrl)s mouse event dialogs here</div>
</div>

{{include "whiff_middleware/jquery/jQueryUIBase"}}
        {{using targetId}} %(promptDialog)s {{/using}}
        {{using widget}} dialog {{/using}}
        {{using option_autoOpen}} false {{/using}}
        {{using option_modal}} true {{/using}}
        {{using option_minWidth}} %(minWidth)s {{/using}}
        {{using option_width}} %(width)s {{/using}}
        {{using option_buttons}}
                {
                        %(buttons)s
                }
        {{/using}}
        {{using method_open}} %(showPromptFnName)s {{/using}}
        {{using method_close}} %(closeFunctionName)s {{/using}}
{{/include}}


"""

DEFAULTBUTTONS = """
"Change": %(changeFunctionName)s,
"Cancel": %(closeFunctionName)s
"""

from whiff.middleware import misc
from whiff import whiffenv
from whiff.middleware import Eval

class EditDialog(misc.utility):
    def __init__(self,
                 editFunctionName,
                 jsonData,
                 displayUrl,
                 editUrl,
                 editPairsAction,
                 editActionUrl,
                 changeFunctionName=None,
                 closeFunctionName=None,
                 buttons=DEFAULTBUTTONS,
                 prefix="EditDialog",
                 width="500",
                 minWidth="300",
                 relativeUrl=None,
                 ):
        # prefix used with generated javascript names
        self.prefix = prefix
        # the javascript name for the action to start the edit dialog
        self.editFunctionName = editFunctionName
        # the json document to edit
        self.jsonData = jsonData
        # the Url of the handler to format the json document as html
        self.displayUrl = displayUrl
        # the Url of the handler to format the edit pop up
        self.editUrl = editUrl
        # javascript name to get the cgi-pair parameters from the edit pop up
        self.editPairsAction = editPairsAction
        # the Url of the handler to generate new json from the edit action
        self.editActionUrl = editActionUrl
        # (optional) javascript name to invoke the edit processing (used in buttons)
        self.changeFunctionName = changeFunctionName
        # (optional) javascript name for function to close the dialog
        self.closeFunctionName = closeFunctionName
        # (optional) buttons for dialog ala jQueryUI (default is save/cancel)
        self.buttons = buttons
        # (optional) dialog width parameters
        self.width = width
        self.minWidth = minWidth
        # (optional) relative url for template evaluation
        self.relativeUrl = relativeUrl
    def __call__(self, env, start_response):
        prefix = self.param_value(self.prefix, env).strip()
        editFunctionName = self.param_value(self.editFunctionName, env).strip()
        jsonData = self.param_value(self.jsonData, env) # string, validate later
        displayUrl = self.param_value(self.displayUrl, env).strip()
        editUrl = self.param_value(self.editUrl, env).strip()
        editActionUrl = self.param_value(self.editActionUrl, env).strip()
        editPairsAction = self.param_value(self.editPairsAction, env)
        buttons = self.param_value(self.buttons, env)
        width = int(self.param_value(self.width, env).strip())
        minWidth = int(self.param_value(self.minWidth, env).strip())
        if self.changeFunctionName is not None:
            changeFunctionName = self.param_value(self.changeFunctionName, env)
        else:
            changeFunctionName = prefix+"_changeFunctionName"
        if self.closeFunctionName is not None:
            closeFunctionName = self.param_value(self.closeFunctionName, env)
        else:
            closeFunctionName = prefix+"_closeFunctionName"
        # validate json
        jsontest = self.param_json(jsonData, env)
        # build substitution dict
        D = {}
        D["prefix"] = prefix
        D["jsonData"] = jsonData
        D["displayUrl"] = displayUrl
        D["editUrl"] = editUrl
        D["editActionUrl"] = editActionUrl
        D["editPairsAction"] = editPairsAction
        D["editFunctionName"] = editFunctionName
        D["width"] = width
        D["minWidth"] = minWidth
        D["changeFunctionName"] = changeFunctionName
        D["closeFunctionName"] = closeFunctionName
        def p(s):
            D[s] = prefix+"_"+s
        p("jsonvar")
        p("updateFnName")
        p("widgetContainer")
        p("showPromptFnName")
        p("promptDiv")
        p("promptDialog")
        # perform substitutions for buttons
        D["buttons"] = buttons % D
        # find the relative url of the calling template (unless overridden)
        if self.relativeUrl is None:
            relativeUrl = env[whiffenv.TEMPLATE_URL]
        else:
            relativeUrl = self.param_value(self.relativeUrl, env)
        #pr "relativUrl=", relativeUrl
        D["relativeUrl"] = relativeUrl
        # generate whiff template
        whiff_text = TEMPLATE % D
        # evaluate the template
        app = Eval.__middleware__(whiff_text, relativeUrl)
        return self.deliver_page(app, env, start_response)

__middleware__ = EditDialog

